<?php
namespace Home\Controller;

use Think\Controller;

/**
 * CommonController
 * 通用控制器
 */
class CommonController extends Controller {
    /**
    * 全局初始化
    * @return
    */
    public function _initialize() {
        // utf-8编码
        header('Content-Type: text/html; charset=utf-8');

        // 安装过滤
        $this->filterInstall();

        // 登录过滤
        $notLoginModules = explode(',', C('NOT_LOGIN_MODULES'));
        if (!in_array(CONTROLLER_NAME, $notLoginModules)) {
            $this->filterLogin();
        }

        // 权限过滤
        $this->filterAccess();

        // 菜单分配
        $noMenuModules = array('Public');
        if (!in_array(CONTROLLER_NAME, $noMenuModules)) {
            // 分配菜单
            $this->assignMenu();
            // 面包屑位置
            $this->assignBreadcrumbs();
        }
    }

    /**
     * 登录过滤
     * @return
     */
    protected function filterLogin() {
        $result = D('Admin', 'Service')->checkLogin();
        if (!$result['status']) {
            return $this->error($result['data']['error'], U('Public/index'));
        }
    }

    /**
     * 权限过滤
     * @return
     */
    protected function filterAccess() {
//        if (!C('USER_AUTH_ON')) {
//            return ;
//        }
//
//        if (\Org\Util\Rbac::AccessDecision(C('GROUP_AUTH_NAME'))) {
//            return ;
//        }
//
//        if (!$_SESSION [C('USER_AUTH_KEY')]) {
//            // 登录认证号不存在
//            return $this->redirect(C('USER_AUTH_GATEWAY'));
//        }
//
//        if ('Index' === CONTROLLER_NAME && 'index' === ACTION_NAME) {
//            // 首页无法进入，则登出帐号
//            D('Admin', 'Service')->logout();
//        }
//
//        return $this->error('您没有权限执行该操作！');
    }

    /**
     * 过滤安装
     * @return
     */
    public function filterInstall() {
        // 不存在初始化的超级管理员则认为未安装
        $installFile = WEB_ROOT . 'install.php';

        $host = C('DB_HOST');
        if (empty($host) || !D('Admin', 'Service')->existInitAdmin()) {
            if (!file_exists($installFile)) {
                echo "缺少<b>{$installFile}</b>文件！";
                exit();
            }

            // 重定向到安装页
            $url = "http://{$_SERVER['HTTP_HOST']}".__ROOT__.'/install.php';
            echo "<script>location.href='{$url}';</script>";
            exit();
        }

        $installDir = WEB_ROOT . 'Install';
        if (is_dir($installDir) && file_exists($installFile)) {
            // 删除安装目录
            del_dir_or_file($installDir, true);
            // 删除安装文件
            del_dir_or_file($installFile);
        }
    }

    /**
     * 是否已登录
     * @return boolean
     */
    protected function hasLogin() {
        $result = D('Admin', 'Service')->checkLogin();

        return $result['status'];
    }

    /**
     * 空操作
     * @return
     */
    public function _empty() {
        $this->error('亲，您访问的页面不存在！');
    }

    /**
     * 得到数据分页
     * @param  string $modelName 模型名称
     * @param  array  $where     分页条件
     * @return array
     */
    protected function getPagination($modelName, $where=[], $fields, $order) {
        $service = D($modelName, 'Service');

        // 总数据行数
        $totalRows = $service->getCount($where);
        // 实例化分页
        $page = new \Org\Util\Page($totalRows, C('PAGE_LIST_ROWS'));
        $result['show'] = $page->show();
        // 得到分页数据
        $data = $service->getPagination($where,
                                        $fields,
                                        $order,
                                        $page->firstRow,
                                        $page->listRows);
        $result['data'] = $data;
        $result['total_rows'] = $totalRows;
        return $result;
    }

    /**
     * 分配菜单
     * @return
     */
    protected function assignMenu() {
        $menu = $this->getMenu();

        $this->assign('main_menu', $menu['main_menu']);
        $this->assign('sub_menu', $menu['sub_menu']);
    }

    /**
     * 分配面包屑
     * @return
     */
    protected function assignBreadcrumbs() {
        $breadcrumbs = $this->getBreadcrumbs();

        $this->assign('breadcrumbs', $breadcrumbs);
    }

    /**
     * 得到菜单
     * @return array
     */
    protected function getMenu() {
        $menu = C('MENU');

        // 主菜单
        $mainMenu = array();
        // 已被映射过的键值
        $mapped = array();

        // 访问权限
        $access = $_SESSION['_ACCESS_LIST'];
        if (empty($access)) {
            $authId = $_SESSION[C('USER_AUTH_KEY')];
            $access = \Org\Util\Rbac::getAccessList($authId);
        }
        $authGroup = strtoupper(C('GROUP_AUTH_NAME'));

        // 处理主菜单
        foreach ($menu as $key => $menuItem) {
            // 不显示无权限访问的主菜单
            if (!$_SESSION[C('ADMIN_AUTH_KEY')]
                && !array_key_exists(strtoupper($key), $access[$authGroup])) {
                continue ;
            }

            // 主菜单是否存在映射
            if (isset($menuItem['mapping'])) {
                // 映射名
                $mapping = $menuItem['mapping'];
                // 新的菜单键值
                if (!empty($mapped[$mapping])) {
                    $key = "{$mapped[$mapping]}-{$key}";
                    $mapping = $mapped[$mapping];
                } else {
                    $key = "{$mapping}-{$key}";
                }

                // 需要映射的键值已存在，则删除
                if (isset($mainMenu[$mapping])) {
                    $mainMenu[$key]['name'] = $mainMenu[$mapping]['name'];
                    $mainMenu[$key]['target'] = $mainMenu[$mapping]['target'];
                    unset($mainMenu[$mapping]);
                    $mapped[$mapping] = $key;
                }

                continue ;
            }

            $mainMenu[$key]['name'] = $menuItem['name'];
            $mainMenu[$key]['target'] = $menuItem['target'];
            
            //如果默认的target用户无权访问，则显示sub_menu中的用户有权访问的第一个页面
            $actions = $access[$authGroup][strtoupper($key)];
            $action = explode('/', strtoupper($mainMenu[$key]['target']));
            while (!$_SESSION[C('ADMIN_AUTH_KEY')] && !array_key_exists($action[1], $actions)) {
                $nextSubMenu = next($menu[$key]['sub_menu']);
                if (empty($nextSubMenu)) break;
                $mainMenu[$key]['target'] = key(current($nextSubMenu));
                $action = explode('/', strtoupper($mainMenu[$key]['target']));
            }
        }

        // 子菜单
        $subMenu = array();
        $ctrlName = $this->getCtrName();
        if (isset($menu[$ctrlName]['mapping'])) {
            $ctrlName = $menu[$ctrlName]['mapping'];
        }

        $actions = $access[$authGroup];
        // 主菜单如果为隐藏，则子菜单也不被显示
        foreach ($menu[$ctrlName]['sub_menu'] as $item) {
            // 子菜单是否需要显示
            if (isset($item['hidden']) && true === $item['hidden']) {
                continue ;
            }

            $route = array_shift(array_keys($item['item']));
            $action = explode('/', strtoupper($route));
            // 不显示无权限访问的子菜单
            if (!$_SESSION[C('ADMIN_AUTH_KEY')]
                && (!array_key_exists($action[0], $actions)
                    || !array_key_exists($action[1], $actions[$action[0]]))) {
                continue ;
            }

            // 子菜单是否有配置
            if (!isset($item['item']) || empty($item['item'])) {
                continue ;
            }

            $routes = array_keys($item['item']);
            $itemNames = array_values($item['item']);
            $subMenu[$routes[0]] = $itemNames[0];
        }

        unset($menu);
        return array(
            'main_menu' => $mainMenu,
            'sub_menu' => $subMenu
        );
    }

    /**
     * 得到面包屑
     * @return string
     */
    public function getBreadcrumbs() {
        $menu = C('MENU');

        $ctrName = $this->getCtrName();
        $menuItem = $menu[$ctrName];
        // 主菜单显示名称
        $main = $menuItem['name'];
        // 子菜单显示名称
        $sub = 'unkonwn';
        $route = $ctrName . '/' . ACTION_NAME;
        foreach ($menuItem['sub_menu'] as $item) {
            // 以键值匹配路由
            if (array_key_exists($route, $item['item'])) {
                $sub = $item['item'][$route];
            }
        }

        return $main . ' > ' . $sub;
    }

    /**
     * { status : true, info: $info}
     * @param  string $info
     * @param  string $url
     * @return
     */
    protected function successReturn($info, $url) {
        $this->resultReturn(true, $info, $url);
    }

    /**
     * { status : false, info: $info}
     * @param  string $info
     * @param  string $url
     * @return
     */
    protected function errorReturn($info, $url) {
        $this->resultReturn(false, $info, $url);
    }

    /**
     * 返回带有status、info键值的json数据
     * @param  boolean $status
     * @param  string $info
     * @param  string $url
     * @return
     */
    protected function resultReturn($status, $info, $url) {
        $json['status'] = $status;
        $json['info'] = $info;
        $json['url'] = isset($url) ? $url : '';

        return $this->ajaxReturn($json);
    }

    /**
     * 下载文件
     * @param  文件路径 $filePath
     * @param  文件名称 $fileName
     * @return
     */
    protected function download($filePath, $fileName) {
        header('Content-Type: application/octet-stream');
        header('Content-Disposition: attachment; '. 'filename="' . $fileName . '"');
        header('Content-Length: ' . filesize($filePath));
        readfile($filePath);
    }

    protected function getCtrName() {
        $ctrName = CONTROLLER_NAME;

        if(strpos($ctrName, '.') !== false && strtoupper($ctrName[0]) === $ctrName[0]) {
            $ctrName[0] = strtolower($ctrName[0]);
        }

        return $ctrName;
    }

    //上传单张图片
    public function imgUpload($filePath){
        if (! file_exists($filePath)) {
            $mode = intval('0777',8);
            mkdir('Public/uploads/'.$filePath, $mode, true);
        }

        $upload = new \Think\Upload();

        // 上传文件
        $info   =   $upload->upload('',$filePath);

        if(!$info) {
            // 上传错误提示错误信息
            $this->error($upload->getError());
        }else{// 上传成功
            return $info;
        }
    }

    // 读取text 并存到数据库
    public function readText($filePath,&$errorCode,&$errorMessage)
    {
        try{
            $file = fopen($filePath, "r"); // 读写文件
            if(empty($file)){
                $errorCode = 201;
                $errorMessage = "file not found";
                return;
            }
            $i = 1;
            //输出文本中所有的行，直到文件结束为止。
            while(!feof($file)) {
                $itemStr = fgets($file); //fgets()函数从文件指针中读取一行
                $itemArray = explode("\t",$itemStr); // 将tab分割的各部分内容提取出来
                $itemArray = array_filter($itemArray); // 对itemArray进行校验

                //小说信息处理
                if($i == 1){
                    $novel_data['title'] = $itemArray[0];
                    $novel_data['author'] = $itemArray[1];
                    $novel_data['is_finish'] = $itemArray[2];
                    $novel_data['is_serial'] = $itemArray[3];
                    $novel_data['fit_crowd'] = $itemArray[4];
                    $novel_data['words_number'] = $itemArray[5];
                    $novel_data['class_id'] = $itemArray[6];
                    $novel_data['label'] = $itemArray[7];
                }elseif ($i == 2){
                    $novel_data['source_addr'] = $itemArray[0];
                    $novel_data['source_url'] = $itemArray[1];
                }elseif ($i == 3){
                    $novel_data['cover'] = $itemArray[0];
                }elseif ($i == 4){
                    $novel_data['intro'] = $itemArray[0];
                }

                $novel_data['create_time'] = $novel_data['update_time'] = time();
                if($novel_data['intro'] && !empty($novel_data['intro'])){
                    $novel_id = $this->addNovel($novel_data);
                    if($novel_id > 0){
                        $_SESSION['novel_id'] = $novel_id;
                    }
                }

                //小说章节处理
                if($i>=11){
                    if($_SESSION['novel_id'] != 0){
                        $chapter_data['title'] = $itemArray[0];
                        $chapter_data['words_number'] = $itemArray[1];
                        $chapter_data['content'] = $itemArray[2];
                        $chapter_data['novel_chapter'] = $i - 10;
                        $chapter_data['novel_id'] = $_SESSION['novel_id'];
                        $chapter_data['create_time'] = $chapter_data['update_time'] = time();
                    }
                }

                //写入章节数据库操作
                $this->addChapterSingle($chapter_data);
                ++$i;
            }
            fclose($file);
        }catch (Exception $exception){
            $errorCode = $exception->getCode();
            $errorMessage = $exception->getMessage();
        }
        return true;
    }

    //添加小说到数据库
    public function addNovel($data){
        $novel_Model = M('novel');
        $is_exist = $novel_Model->where(['title'=>$data['title'],'author'=>$data['author'],'is_del'=>0])->find();
        if($is_exist){
            return 0;
        }

        $result = $novel_Model->add($data);

        return $result?$result:0;
    }

    //添加章节到数据库  数组形式添加
    public function addChapter($data){
        $novel_Model = M('chapter');
        $is_exist = $novel_Model->where(['novel_id'=>$data[0]['novel_id'],'novel_chapter'=>$data[0]['novel_chapter'],'is_del'=>0])->find();
        if($is_exist){
            return 0;
        }
        $result = $novel_Model->addAll($data);
        return $result?$result:0;
    }

    //添加章节到数据库  单条形式添加
    public function addChapterSingle($data){
        $novel_Model = M('chapter');
        $is_exist = $novel_Model->where(['novel_id'=>$data['novel_id'],'novel_chapter'=>$data['novel_chapter'],'is_del'=>0])->find();
        if($is_exist){
            return 0;
        }
        $result = $novel_Model->add($data);
        return $result?$result:0;
    }


    // 解析text为数组
    public function textToArr($filePath,&$errorCode,&$errorMessage)
    {
        $data = [];
        try{
            $file = fopen($filePath, "r"); // 读写文件
            if(empty($file)){
                $errorCode = 201;
                $errorMessage = "file not found";
                return;
            }
            $i = 1;
            //输出文本中所有的行，直到文件结束为止。

            $show_chapter_data = [];
            while(!feof($file)) {
                $itemStr = fgets($file); //fgets()函数从文件指针中读取一行
                $itemArray = explode("\t",$itemStr); // 将tab分割的各部分内容提取出来
                $itemArray = array_filter($itemArray); // 对itemArray进行校验

                //小说信息处理
                if($i == 1){
                    $novel_data['title'] = $itemArray[0];
                    $novel_data['author'] = $itemArray[1];
                    $novel_data['is_finish'] = $itemArray[2];
                    $novel_data['is_serial'] = $itemArray[3];
                    $novel_data['fit_crowd'] = $itemArray[4];
                    $novel_data['words_number'] = $itemArray[5];
                    $novel_data['class_id'] = $itemArray[6];
                    $novel_data['label'] = $itemArray[7];
                }elseif ($i == 2){
                    $novel_data['source_addr'] = $itemArray[0];
                    $novel_data['source_url'] = $itemArray[1];
                }elseif ($i == 3){
                    $novel_data['cover'] = $itemArray[0];
                }elseif ($i == 4){
                    $novel_data['intro'] = $itemArray[0];
                }

                $data['novel_info'] = $novel_data;

                //小说章节处理
                if($i>=11){
                    $chapter_data['title'] = $itemArray[0];
                    $chapter_data['words_number'] = $itemArray[1];
                    $chapter_data['content'] = $itemArray[2];
                    $chapter_data['novel_chapter'] = $i - 10;

                    $show_chapter_data[] = $chapter_data;
                }

                //写入章节数据库操作
                $data['chapter_data'] = $show_chapter_data;
                ++$i;
            }
            fclose($file);
        }catch (Exception $exception){
            $errorCode = $exception->getCode();
            $errorMessage = $exception->getMessage();
        }
        return $data;
    }


    public function unzip($src_file, $dest_dir=false, $create_zip_name_dir=true, $overwrite=true){

        $filePath_arr = [];
        if ($zip = zip_open($src_file)){
            if ($zip){
                $splitter = ($create_zip_name_dir === true) ? "." : "/";
                if($dest_dir === false){
                    $dest_dir = substr($src_file, 0, strrpos($src_file, $splitter))."/";
                }

                // 如果不存在 创建目标解压目录
                $this->create_dirs($dest_dir);

                // 对每个文件进行解压
                while ($zip_entry = zip_read($zip)){
                    // 文件不在根目录
                    $pos_last_slash = strrpos(zip_entry_name($zip_entry), "/");
                    if ($pos_last_slash !== false){
                        // 创建目录 在末尾带 /
                        $this->create_dirs($dest_dir.substr(zip_entry_name($zip_entry), 0, $pos_last_slash+1));
                    }

                    // 打开包
                    if (zip_entry_open($zip,$zip_entry,"r")){

                        // 文件名保存在磁盘上
                        $file_name = $dest_dir.zip_entry_name($zip_entry);

                        // 检查文件是否需要重写

                        if ($overwrite === true || $overwrite === false && !is_file($file_name)){
                            // 读取压缩文件的内容
                            $fstream = zip_entry_read($zip_entry, zip_entry_filesize($zip_entry));

                            @file_put_contents($file_name, $fstream);
                            // 设置权限
                            chmod($file_name, 0777);
//                            echo "save: ".$file_name."<br />";
                            $extension = $this->get_extension($file_name);
                            if($extension){
                                $filePath_arr[] = $file_name;
                            }
                        }

                        // 关闭入口
                        zip_entry_close($zip_entry);
                    }
                }
                // 关闭压缩包
                zip_close($zip);
            }
        }else{
            return false;
        }
        return $filePath_arr;
    }

    /**
     * 创建目录
     */
    public function create_dirs($path){
        if (!is_dir($path)){
            $directory_path = "";
            $directories = explode("/",$path);
            array_pop($directories);

            foreach($directories as $directory){
                $directory_path .= $directory."/";
                if (!is_dir($directory_path)){
                    mkdir($directory_path);
                    chmod($directory_path, 0777);
                }
            }
        }
    }

    //获取文件后缀
    function get_extension($file)
    {
        return substr(strrchr($file, '.'), 1);
    }



}
